home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 June
/
EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso
/
earcd
/
cmdity
/
realdrag.lha
/
RealDrag.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-26
|
10KB
|
421 lines
/* $VER: RealDrag.c 1.0 (23.4.96)
RealDrag by Stuart Monteith
Allows windows to be dragged, while their contents are still shown.
Note: This source is Public Domain. Hell, this program should have been
written years ago.
*/
#include <dos/dos.h>
#include <devices/inputevent.h>
#include <exec/types.h>
#include <exec/libraries.h>
#include <intuition/intuitionbase.h>
#include <libraries/commodities.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <clib/exec_protos.h>
#include <clib/commodities_protos.h>
#include <clib/icon_protos.h>
struct NewBroker newBroker= {
NB_VERSION,
"RealDrag",
"RealDrag 1.0 Apr-96 Stuart Monteith",
"Alternative filled window dragging",
NBU_NOTIFY | NBU_UNIQUE, /* Tell me when another me is started */
0, /* No flags. ie. no Show & Hide */
4, /* Priority. To be set */
NULL, /* Message port. To Be Set */
0 /* Unused */
};
void Cleanup(char *errStr,ULONG errNum); /* Call to exit */
void RealMain(void);
/* This is a custom CxObject, to be executed on input.device's task.
* __geta4 as we are compiled as a small-code model. */
__geta4 void CxStripQualifier(CxMsg *cxm,CxObj *co);
struct IntuitionBase *IntuitionBase=NULL;
struct Library *CxBase=NULL,*IconBase=NULL;
extern struct Library *DOSBase;
struct MsgPort *msgPort=NULL;
CxObj *broker=NULL,*filter=NULL,*sender=NULL,*stripqual=NULL;
#define CXID_SENDER1 0xCED1
/* Used by filter to direct mouse movements to us */
IX ix = {
IX_VERSION, /* IXVersion */
IECLASS_RAWMOUSE, /* Class */
0, /* Code */
0, /* CodeMask*/
0, /* Qualifier */
0, /* Qualifier mask */
0};
char *vers="$VER: RealDrag.c 1.0 (23.4.96)";
/* ReadArgs */
#define NUM_ARGS 12 /* # of args */
/* The ReadArgs array indices */
#define ARG_CX_PRIORITY 0
#define ARG_TASKPRI 1
#define ARG_CTRL 2
#define ARG_LSHIFT 3
#define ARG_RSHIFT 4
#define ARG_LALT 5
#define ARG_RALT 6
#define ARG_LAMIGA 7
#define ARG_RAMIGA 8
#define ARG_LBUTTON 9
#define ARG_RBUTTON 10
#define ARG_MBUTTON 11
/* The ReadArgs template */
char *template="CX_PRIORITY/N/K,TASKPRI/N/K,CTRL/S"
",LSHIFT/S,RSHIFT/S,LALT/S,RALT/S,LAMIGA/S,RAMIGA/S,"
"LBUTTON/S,RBUTTON/S,MBUTTON/S";
LONG Args[NUM_ARGS];
struct RDArgs *rdArgs = NULL;
BOOL FromWB; /* True if launched from WB, false if from DOS */
/* An EasyRequester displaying an error from WB */
struct EasyStruct ez ={
sizeof(struct EasyStruct), /* Struct Size */
0, /* Flags */
"RealDrag", /* Title */
"Error:\n%s", /* Text Format */
"Understood" /* Gadget Format */
};
/* Workbench startup stuff */
int wbmain(struct WBStartup *ws)
{
struct WBArg *wbArg;
struct DiskObject *icon;
BPTR oldlock;
char *tt; /* ToolType */
FromWB=TRUE;
if(!(IconBase = OpenLibrary("icon.library",36)))
Cleanup("Unable to open icon.library V36",
ERROR_INVALID_RESIDENT_LIBRARY);
/* If just Tool icon, use that, else use first project icon */
if(ws->sm_NumArgs == 1)
wbArg = &(ws->sm_ArgList[0]);
else
wbArg = &(ws->sm_ArgList[1]);
oldlock = CurrentDir(wbArg->wa_Lock);
if(!(icon = (struct DiskObject *) GetDiskObject(wbArg->wa_Name)))
{
CurrentDir(oldlock); /* Important!*/
Cleanup("Unable to get icon",IoErr());
}
CurrentDir(oldlock);
if(tt = FindToolType(icon->do_ToolTypes,"CX_PRIORITY"))
newBroker.nb_Pri = (BYTE) atoi(tt);
/* All of these args may follow `QUALIFIER=', separated by | */
if(tt = FindToolType(icon->do_ToolTypes,"QUALIFIER"))
{
if(MatchToolValue(tt,"CTRL"))
ix.ix_Qualifier |= IEQUALIFIER_CONTROL;
if(MatchToolValue(tt,"LSHIFT"))
ix.ix_Qualifier |= IEQUALIFIER_LSHIFT;
if(MatchToolValue(tt,"RSHIFT"))
ix.ix_Qualifier |= IEQUALIFIER_RSHIFT;
if(MatchToolValue(tt,"LALT"))
ix.ix_Qualifier |= IEQUALIFIER_LALT;
if(MatchToolValue(tt,"RALT"))
ix.ix_Qualifier |= IEQUALIFIER_RALT;
if(MatchToolValue(tt,"LAMIGA"))
ix.ix_Qualifier |= IEQUALIFIER_LCOMMAND;
if(MatchToolValue(tt,"RAMIGA"))
ix.ix_Qualifier |= IEQUALIFIER_RCOMMAND;
if(MatchToolValue(tt,"LBUTTON"))
ix.ix_Qualifier |= IEQUALIFIER_LEFTBUTTON;
if(MatchToolValue(tt,"RBUTTON"))
ix.ix_Qualifier |= IEQUALIFIER_RBUTTON;
if(MatchToolValue(tt,"MBUTTON"))
ix.ix_Qualifier |= IEQUALIFIER_MIDBUTTON;
}
FreeDiskObject(icon);
RealMain();
}
int main(int argc,char *argv[])
{
int cnt;
FromWB = FALSE;
if(DOSBase->lib_Version <36)
{
printf("RealDrag: Wrong DOS version - upgrade to 2.0 or above!\n");
exit(ERROR_INVALID_RESIDENT_LIBRARY);
}
/* NULL all args */
for(cnt=0;cnt < NUM_ARGS;cnt++) Args[cnt] = 0l;
if(!(rdArgs = (struct RDArgs *) ReadArgs(template,Args,NULL)))
{
PrintFault(ERROR_REQUIRED_ARG_MISSING,"RealDrag: ");
exit(ERROR_REQUIRED_ARG_MISSING);
}
if(Args[ARG_CX_PRIORITY])
newBroker.nb_Pri = (BYTE) *((LONG *) Args[ARG_CX_PRIORITY]);
if(Args[ARG_TASKPRI])
SetTaskPri(FindTask(NULL),*((LONG *) Args[ARG_TASKPRI]));
if(Args[ARG_CTRL])
ix.ix_Qualifier |= IEQUALIFIER_CONTROL;
if(Args[ARG_LSHIFT])
ix.ix_Qualifier |= IEQUALIFIER_LSHIFT;
if(Args[ARG_RSHIFT])
ix.ix_Qualifier |= IEQUALIFIER_RSHIFT;
if(Args[ARG_LALT])
ix.ix_Qualifier |= IEQUALIFIER_LALT;
if(Args[ARG_RALT])
ix.ix_Qualifier |= IEQUALIFIER_RALT;
if(Args[ARG_LAMIGA])
ix.ix_Qualifier |= IEQUALIFIER_LCOMMAND;
if(Args[ARG_RAMIGA])
ix.ix_Qualifier |= IEQUALIFIER_RCOMMAND;
if(Args[ARG_LBUTTON])
ix.ix_Qualifier |= IEQUALIFIER_LEFTBUTTON;
if(Args[ARG_RBUTTON])
ix.ix_Qualifier |= IEQUALIFIER_RBUTTON;
if(Args[ARG_MBUTTON])
ix.ix_Qualifier |= IEQUALIFIER_MIDBUTTON;
RealMain();
}
void RealMain(void)
{
LONG brokerErr;
if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",36L)))
Cleanup("Unable to open intuition.library",36);
if(!(CxBase = OpenLibrary("commodities.library",36)))
Cleanup("Unable to open commodities.library",
ERROR_INVALID_RESIDENT_LIBRARY);
if(!(msgPort = CreateMsgPort()))
Cleanup("Unable to create msgport",
RETURN_FAIL);
/* We care about our qualifiers */
ix.ix_QualMask = ix.ix_Qualifier;
newBroker.nb_Port = msgPort;
if(!(broker = CxBroker(&newBroker,&brokerErr)))
{
switch(brokerErr)
{
case CBERR_SYSERR:
Cleanup("Can't create broker - syserr",RETURN_FAIL);
case CBERR_DUP:
Cleanup(NULL,0);
case CBERR_VERSION:
Cleanup("Wrong NewBroker struct version.",RETURN_FAIL);
default:
Cleanup("Can't create broker - don't know why",RETURN_FAIL);
}
}
/* Checks for qualifier AFTER trying to create broker. This allows realdrag
* to kill itself without any arguments being present. */
if(! ix.ix_Qualifier)
Cleanup("You MUST choose a qualifier!",ERROR_REQUIRED_ARG_MISSING);
if(!(filter = CxFilter("rawmouse ctrl leftbutton lmouse")))
Cleanup("Unable to create filter",RETURN_FAIL);
SetFilterIX(filter,&ix);
if(!(sender = CxSender(msgPort,CXID_SENDER1)))
Cleanup("Unable to create sender",RETURN_FAIL);
if(!(stripqual = CxCustom(CxStripQualifier,0)))
Cleanup("Unable to create custom `CxStripQualifier'",RETURN_FAIL);
AttachCxObj(broker,filter);
AttachCxObj(filter,sender);
AttachCxObj(filter,stripqual);
{ WORD quit=0;
CxMsg *msg;
WORD cx=0,cy=0,lx,ly,nx,ny;
ULONG signal,msgid,msgtype,msgmask,brkmask,waitmask;
struct InputEvent ie;
struct Window *aw,*lw;
msgmask = 1 << msgPort->mp_SigBit;
brkmask = SIGBREAKF_CTRL_C;
waitmask = msgmask | brkmask;
ActivateCxObj(broker,1);
while(!quit)
{
signal = Wait(waitmask);
if(signal & msgmask){
while(msg = (CxMsg *) GetMsg(msgPort))
{
msgid = CxMsgID(msg);
msgtype = CxMsgType(msg);
if(msgtype == CXM_IEVENT)
ie = *((struct InputEvent *) CxMsgData(msg));
ReplyMsg((struct Message *) msg);
switch(msgtype)
{
case CXM_IEVENT:
if(msgid == CXID_SENDER1)
{
if(!(ie.ie_Qualifier &
(~(ix.ix_Qualifier | 0x8c00))))
{ aw = IntuitionBase->ActiveWindow;
/* only drag dragable windows! */
if(aw->Flags & WFLG_DRAGBAR)
{
nx = aw->WScreen->MouseX - (aw->Width>>1);
ny = aw->WScreen->MouseY - (aw->Height>>1);
/* Move window only if to new pos. */
if(!((aw == lw) &&
(nx == lx) && (ny == ly)))
{
MoveWindow(aw,
nx - aw->LeftEdge,ny-aw->TopEdge);
}
lx = nx; ly = ny; lw = aw;
}
}
}
break;
case CXM_COMMAND:
switch(msgid)
{
case CXCMD_DISABLE:
ActivateCxObj(broker,0);
break;
case CXCMD_ENABLE:
ActivateCxObj(broker,1);
break;
/* If run twice or CX said so, die */
case CXCMD_UNIQUE:
case CXCMD_KILL:
quit = 1;
break;
}
break;
}
}}
else if(signal & brkmask)
quit = 1;
}
}
Cleanup(NULL,0);
}
/* This my Custom CX object. As a CxTranslate(NULL) couldn't be used (it
stripped off the mouse movements), I need this to simply strip off the
qualifiers & codes allowing intuition to move the pointer. */
__geta4 void CxStripQualifier(CxMsg *cxm,CxObj *co)
{
struct InputEvent *ie;
ie = (struct InputEvent *) CxMsgData(cxm);
/* Only remove when I am dragging - using same critera. */
if(!(ie->ie_Qualifier & ~(ix.ix_Qualifier | 0x8c00)))
{ ie->ie_Qualifier = 0;
ie->ie_Code = 0;
}
}
/* Cleans up, no matter what */
void Cleanup(char *errStr,ULONG errNum)
{
if(stripqual)
DeleteCxObj(stripqual);
if(sender)
DeleteCxObj(sender);
if(filter)
DeleteCxObj(filter);
if(broker)
DeleteCxObj(broker);
if(msgPort)
DeletePort(msgPort);
if(CxBase)
CloseLibrary(CxBase);
if(rdArgs)
FreeArgs(rdArgs);
if(IconBase)
CloseLibrary(IconBase);
if(errStr)
{
if(FromWB)
{
if(!IntuitionBase)
IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",36l);
if(IntuitionBase)
EasyRequest(NULL,&ez,NULL,errStr);
}
else
printf("RealDrag: %s\n",errStr);
}
if(IntuitionBase)
CloseLibrary((struct Library *)IntuitionBase);
exit(errNum);
}